package com.jsyl.lwbk.business.handle;

import com.jsyl.lwbk.business.domain.*;
import com.jsyl.lwbk.business.dto.EvaluateModuleScoreDTO;
import com.jsyl.lwbk.business.dto.ModuleMaxCountScoreDTO;
import com.jsyl.lwbk.business.dto.ProjectModuleScoreDTO;
import com.jsyl.lwbk.business.mapper.*;
import com.jsyl.lwbk.business.service.IGenerateProgramService;
import com.jsyl.lwbk.common.utils.AgeUtils;
import com.jsyl.lwbk.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author xiaoshu
 * @date 2020-12-27 01:21
 * @desc 计算分数
 **/
@Component
public class CalculateEvaluateScoreHandle {

    @Autowired
    private EvaluateReportMapper evaluateReportMapper;
    @Autowired
    private EvaluateRecordMapper evaluateRecordMapper;
    @Autowired
    private ScaleEvaluateModuleMapper scaleEvaluateModuleMapper;
    @Autowired
    private ScaleProjectModuleMapper scaleProjectModuleMapper;
    @Autowired
    private EvaluateScoreMapper evaluateScoreMapper;
    @Autowired
    ChildMapper childMapper;
    @Autowired
    RemarkDataCleanHandle remarkDataCleanHandle;

    @Autowired
    private IGenerateProgramService generateProgramService;
    /**
     * 计算测评分数
     *
     * @param evaluateNumber
     * @return
     */
    public Boolean handle(String evaluateNumber, String teacherName) {
        EvaluateReport evaluateReport = evaluateReportMapper.findByEvaluateNumber(evaluateNumber);
        Child child = childMapper.selectById(evaluateReport.getChildId());


        //计算小孩生理年龄，以月为单位
        Integer childMonth = DateUtils.dayCompare(DateUtils.parseDate(child.getBirthYear() + "-" + child.getBirthMonth() + "-" + child.getBirthDay()), new Date());

        List<EvaluateScore> evaluateModuleScoreList = calculateEvaluateModule(evaluateReport, child, childMonth);
        List<EvaluateScore> evaluateProjectScoreList = calculateEvaluateProject(evaluateReport, child, childMonth);
        for (EvaluateScore evaluateModuleScore : evaluateModuleScoreList) {
            evaluateScoreMapper.insert(evaluateModuleScore);
        }
        for (EvaluateScore evaluateModuleScore : evaluateProjectScoreList) {
            evaluateScoreMapper.insert(evaluateModuleScore);
        }
        evaluateReport.setStatus(0);
        evaluateReport.setUpdateTime(new Date());
        evaluateReport.setUpdateBy(teacherName);
        evaluateReportMapper.updateById(evaluateReport);
        //按产品需求测评完不需要触发生成项目，不确定此时是否排课
        //2022-03-30增加需求，第一次测评时需要生成训练项目，并且查看测评记录时预览训练项目,第二次之后删除未确认得预览项目，按照新测评生成项目
        int evaluateCount = evaluateReportMapper.selectEvaluateCount(evaluateNumber,evaluateReport.getChildId());
        if(evaluateCount==0){
            generateProgramService.generateCurDayChildTraningProgram(evaluateNumber,evaluateReport.getCenterId(),child.getId());
        }else {
            //删除之前测评生成得未确认得预览项目
            this.evaluateReportMapper.delPreviewProgram(evaluateNumber,child.getId());
        }
//        generateProgramService.generateCurDayChildTraningProgram(evaluateNumber,child.getCenterId(),child.getId());
        return Boolean.TRUE;
    }

    /**
     * 计算测评模块
     * 目前规则：
     * 优先判断分值区间，在分值区间的基础上，判断技能年龄是否符合生理年龄。符合的话，则需要去获取小孩正常的测评结果。不符合，则直接返回异常测评结果
     * 数据库规则：年龄可为空(情绪模块)，无分数区间则为标准的正确答案
     */
    private List<EvaluateScore> calculateEvaluateModule(EvaluateReport evaluateReport, Child child, Integer childMonth) {
        List<EvaluateModuleScoreDTO> evaluateModuleScoreDTOList = evaluateRecordMapper.selectEvaluateModuleScore(evaluateReport.getEvaluateNumber());
        List<EvaluateScore> list = new ArrayList<>();
        String tempStr="<br/>儿童并未存在明显的构音方面的不足与困扰，在日常中可能存在语速过快时出现含糊、吞音等情况，但并不影响到个体的日常沟通和社会交往。可以考虑增加会话技巧的训练，或将训练支持的重心放到其他方面。";
        for (EvaluateModuleScoreDTO evaluateModuleScoreDTO : evaluateModuleScoreDTOList) {
            Integer scaleType = scaleEvaluateModuleMapper.selectEvaluateModuleScaleType(evaluateModuleScoreDTO.getEvaluateModule());
            String remark;
            switch (scaleType) {
                case 1://分数
                    remark = evaluateModuleScaleSum(evaluateModuleScoreDTO, childMonth);
                    break;
                case 2://数量
                    remark = evaluateModuleScaleCount(evaluateModuleScoreDTO, evaluateReport, childMonth);
                    break;
                default:
                    remark = "暂无对应反馈";
            }
            //口腔及构音增加总结
            if(evaluateModuleScoreDTO.getEvaluateModule()>=14 && evaluateModuleScoreDTO.getEvaluateModule()<=18 && evaluateModuleScoreDTO.getTotalScore()>0){
                tempStr="<br/>建议增加大量的唇、颊、舌的相关肌肉刺激与按摩，大量为儿童提供语言要素的储备，为儿童语言发展做好准备。此外，儿童还需要大量的针对基础词汇的发音训练。";
            }
            if(evaluateModuleScoreDTO.getEvaluateModule()==18){
                remark+=tempStr;
            }
            remark = remarkDataCleanHandle.clean(remark, AgeUtils.buildAge(child.getBirthYear(), child.getBirthMonth(), child.getBirthDay()));
            EvaluateScore evaluateScore = creationEvaluateScore(child, evaluateReport.getEvaluateNumber(), evaluateModuleScoreDTO.getProjectModule(), evaluateModuleScoreDTO.getEvaluateModule(), evaluateModuleScoreDTO.getTotalScore(), evaluateModuleScoreDTO.getTotalQuestionScore(), remark);
            list.add(evaluateScore);
        }
        return list;
    }

    /**
     * 计算项目模块
     * 目前规则：
     * 判断分值区间,返回对应测评结果
     */
    private List<EvaluateScore> calculateEvaluateProject(EvaluateReport evaluateReport, Child child, Integer childMonth) {
        List<ProjectModuleScoreDTO> projectModuleScoreDTOList = evaluateRecordMapper.selectProjectModuleScore(evaluateReport.getEvaluateNumber());
        List<EvaluateScore> list = new ArrayList<>();
        for (ProjectModuleScoreDTO projectModuleScoreDTO : projectModuleScoreDTOList) {
            Integer scaleType = scaleProjectModuleMapper.selectProjectModuleScaleType(projectModuleScoreDTO.getProjectModule());
            String remark;
            switch (scaleType) {
                case 1://分数
                    remark = projectModuleScaleSum(projectModuleScoreDTO);
                    break;
                case 2://数量
                    remark = projectModuleScaleCount(projectModuleScoreDTO, evaluateReport);
                    break;
                default:
                    remark = "暂无对应反馈";
            }
            remark = remarkDataCleanHandle.clean(remark, AgeUtils.buildAge(child.getBirthYear(), child.getBirthMonth(), child.getBirthDay()));
            EvaluateScore evaluateScore = creationEvaluateScore(child, evaluateReport.getEvaluateNumber(), projectModuleScoreDTO.getProjectModule(), null, projectModuleScoreDTO.getTotalScore(), projectModuleScoreDTO.getTotalQuestionScore(), remark);
            list.add(evaluateScore);
        }
        return list;
    }

    /**
     * 项目模块获取反馈-数值求和
     *
     * @param projectModuleScoreDTO
     * @return
     */
    private String projectModuleScaleSum(ProjectModuleScoreDTO projectModuleScoreDTO) {
        List<ScaleProjectModule> scaleProjectModuleList = scaleProjectModuleMapper.findByScore(projectModuleScoreDTO.getProjectModule(), projectModuleScoreDTO.getTotalScore());
        if (scaleProjectModuleList == null || scaleProjectModuleList.size() < 1) {
            return "暂无对应反馈";
        }
        ScaleProjectModule scaleProjectModule = scaleProjectModuleList.get(0);
        return scaleProjectModule.getRemark();
    }

    /**
     * 项目模块获取反馈-次数最多
     *
     * @param projectModuleScoreDTO
     * @param evaluateReport
     * @return
     */
    private String projectModuleScaleCount(ProjectModuleScoreDTO projectModuleScoreDTO, EvaluateReport evaluateReport) {
        ModuleMaxCountScoreDTO projectModuleMaxCountScoreDTO = evaluateRecordMapper.findMaxAnswerCountByProjectModule(evaluateReport.getEvaluateNumber(), projectModuleScoreDTO.getProjectModule());

        List<ScaleProjectModule> scaleProjectModuleList = scaleProjectModuleMapper.findByCount(projectModuleScoreDTO.getProjectModule(), Integer.valueOf(projectModuleMaxCountScoreDTO.getAnswer()));
        if (scaleProjectModuleList == null || scaleProjectModuleList.size() < 1) {
            return "暂无对应反馈";
        }
        ScaleProjectModule scaleEvaluateModule = scaleProjectModuleList.get(0);
        return scaleEvaluateModule.getRemark();
    }

    /**
     * 测评模块获取反馈-数值求和
     *
     * @param evaluateModuleScoreDTO
     * @param childMonth
     * @return
     */
    private String evaluateModuleScaleSum(EvaluateModuleScoreDTO evaluateModuleScoreDTO, Integer childMonth) {
        List<ScaleEvaluateModule> scaleEvaluateModuleList = scaleEvaluateModuleMapper.findByScore(evaluateModuleScoreDTO.getEvaluateModule(), evaluateModuleScoreDTO.getTotalScore());
        if (scaleEvaluateModuleList == null || scaleEvaluateModuleList.size() < 1) {
            return "暂无对应反馈";
        }
        ScaleEvaluateModule scaleEvaluateModule = scaleEvaluateModuleList.get(0);
        if (scaleEvaluateModule.getAgeStart() != null && scaleEvaluateModule.getAgeEnd() != null
                 && childMonth <= scaleEvaluateModule.getAgeEnd()) {
            //有技能年龄时，需要比较小孩年龄
            //生理年龄在技能年龄合理番位内时，需要查找对应正确的量表
            ScaleEvaluateModule findRight = scaleEvaluateModuleMapper.findRightByScore(evaluateModuleScoreDTO.getEvaluateModule());
            return findRight.getRemark();
        } else {
            return scaleEvaluateModule.getRemark();
        }
    }

    /**
     * 测评模块获取反馈-次数最多
     * 目前对于这块，没什么好的办法，只能默认写死
     * author xiaoshu 2020-12-28
     *
     * @param evaluateModuleScoreDTO
     * @param evaluateReport
     * @return
     */
    private String evaluateModuleScaleCount(EvaluateModuleScoreDTO evaluateModuleScoreDTO, EvaluateReport evaluateReport, Integer childMonth) {
        ModuleMaxCountScoreDTO evaluateModuleMaxCountScoreDTO = evaluateRecordMapper.findMaxAnswerCount(evaluateReport.getEvaluateNumber(), evaluateModuleScoreDTO.getEvaluateModule());
        Integer tallyType = null;
        switch (Integer.valueOf(evaluateModuleMaxCountScoreDTO.getAnswer())) {
            //语言 表达与沟通	 模块ID 6
            //认知 知识与技能  模块ID 8
            //社交 社会性互动  模块ID 9
            //情绪理解  模块ID 20
            //情绪表达  模块ID 21
            case 4:
                //认知
                //选择“4”的数量最多且数量≧6    1
                //选择“4”的数量最多但数量<6    2
                if (evaluateModuleScoreDTO.getEvaluateModule().equals(8)) {
                    if (evaluateModuleMaxCountScoreDTO.getCountNum() >= 6) {
                        tallyType = 1;
                    } else {
                        tallyType = 2;
                    }
                }
                //社交
                //选择“4”的数量最多且数量≧5	3
                //选择“4”的数量最多但数量<5    4
                if (evaluateModuleScoreDTO.getEvaluateModule().equals(9)) {
                    if (evaluateModuleMaxCountScoreDTO.getCountNum() >= 5) {
                        tallyType = 3;
                    } else {
                        tallyType = 4;
                    }
                }
                //语言
                //选择“4”的数量最多且数量≧7	5
                //选择“4”的数量最多且数量<7	6
                if (evaluateModuleScoreDTO.getEvaluateModule().equals(6)) {
                    if (evaluateModuleMaxCountScoreDTO.getCountNum() >= 7) {
                        tallyType = 5;
                    } else {
                        tallyType = 6;
                    }
                }
                //情绪理解  模块ID 20
                //情绪表达  模块ID 21
                if(evaluateModuleScoreDTO.getEvaluateModule().equals(20)||
                        evaluateModuleScoreDTO.getEvaluateModule().equals(21)){
                    tallyType = 4;
                }
                break;
            case 3:
                //选择“3”的数量最多	7
                tallyType = 7;
                //情绪理解  模块ID 20
                //情绪表达  模块ID 21
                if(evaluateModuleScoreDTO.getEvaluateModule().equals(20)||
                        evaluateModuleScoreDTO.getEvaluateModule().equals(21)){
                    tallyType = 3;
                }
                break;
            case 2:
                //选择“2”的数量最多	8
                tallyType = 8;
                //情绪理解  模块ID 20
                //情绪表达  模块ID 21
                if(evaluateModuleScoreDTO.getEvaluateModule().equals(20)||
                        evaluateModuleScoreDTO.getEvaluateModule().equals(21)){
                    tallyType = 2;
                }
                break;
            case 1:
                //语言
                //认知
                //选择“1”的数量最多且数量<6	9
                //选择“1”的数量最多且数量≧6	10
                if (evaluateModuleScoreDTO.getEvaluateModule().equals(8) || evaluateModuleScoreDTO.getEvaluateModule().equals(6)) {
                    if (evaluateModuleMaxCountScoreDTO.getCountNum() >= 6) {
                        tallyType = 10;
                    } else {
                        tallyType = 9;
                    }
                }
                //社交
                //选择“1”的数量最多且数量<5	11
                //选择“1”的数量最多且数量≧5	12
                if (evaluateModuleScoreDTO.getEvaluateModule().equals(9)) {
                    if (evaluateModuleMaxCountScoreDTO.getCountNum() >= 5) {
                        tallyType = 12;
                    } else {
                        tallyType = 11;
                    }
                }
                //情绪理解  模块ID 20
                //情绪表达  模块ID 21
                if(evaluateModuleScoreDTO.getEvaluateModule().equals(20)||
                        evaluateModuleScoreDTO.getEvaluateModule().equals(21)){
                    tallyType = 1;
                }
                break;
            case 0:
                //社交
                //选择“0”的数量最多	        13
                if (evaluateModuleScoreDTO.getEvaluateModule().equals(9)) {
                    tallyType = 13;
                }
                //语言
                //认知
                //选择“0”的数量最多且数量<6	14
                //选择“0”的数量最多且数量≧6	15
                if (evaluateModuleScoreDTO.getEvaluateModule().equals(8) || evaluateModuleScoreDTO.getEvaluateModule().equals(6)) {
                    if (evaluateModuleMaxCountScoreDTO.getCountNum() >= 6) {
                        tallyType = 15;
                    } else {
                        tallyType = 14;
                    }
                }
                //情绪理解  模块ID 20
                //情绪表达  模块ID 21
                if(evaluateModuleScoreDTO.getEvaluateModule().equals(20)||
                        evaluateModuleScoreDTO.getEvaluateModule().equals(21)){
                    tallyType = 0;
                }
                break;
            default:
                return "暂无对应反馈";
        }
        if (tallyType == null) {
            return "暂无对应反馈";
        }
        List<ScaleEvaluateModule> scaleEvaluateModuleList = scaleEvaluateModuleMapper.findByCount(evaluateModuleScoreDTO.getEvaluateModule(), tallyType);
        if (scaleEvaluateModuleList == null || scaleEvaluateModuleList.size() < 1) {
            return "暂无对应反馈";
        }
        ScaleEvaluateModule scaleEvaluateModule = scaleEvaluateModuleList.get(0);
        if (scaleEvaluateModule.getAgeStart() != null && scaleEvaluateModule.getAgeEnd() != null
                 && childMonth <= scaleEvaluateModule.getAgeEnd()) {
            //有技能年龄时，需要比较小孩年龄
            //生理年龄在技能年龄合理番位内时，需要查找对应正确的量表
            ScaleEvaluateModule findRight = scaleEvaluateModuleMapper.findRightByCount(evaluateModuleScoreDTO.getEvaluateModule());
            return findRight.getRemark();
        } else {
            return scaleEvaluateModule.getRemark();
        }
    }

    /**
     * 构造测评分数
     */
    private EvaluateScore creationEvaluateScore(Child child, String evaluateNumber, Integer projectModule, Integer evaluateModule, Integer score, Integer totalScore, String remark) {
        EvaluateScore evaluateScore = new EvaluateScore();
        evaluateScore.setCenterId(child.getCenterId());
        evaluateScore.setChildId(child.getId());
        evaluateScore.setEvaluateNumber(evaluateNumber);
        evaluateScore.setProjectType(1);
        evaluateScore.setProjectModule(projectModule);
        evaluateScore.setEvaluateModule(evaluateModule);
        evaluateScore.setScore(score);
        evaluateScore.setTotalScore(totalScore);
        evaluateScore.setReportRemark(remark);
        return evaluateScore;
    }

}
